#ifndef BLOCKQUEUE_H
#define BLOCKQUEUE_H
#include "../lock/threadlocker.h"
#include "../lock/condition.h"

template <class T>
class BlockQueue
{
public:
    BlockQueue(int max_size) : max_size(max_size), now_size(0), frontpos(-1), backpos(-1)
    {
        blockptr = new T[max_size];
    }
    ~BlockQueue()
    {
        delete[] blockptr;
    }

private:
    int max_size;
    int now_size;
    int frontpos;
    int backpos;
    T *blockptr;
    threadlocker locker;
    condition cond;

public:
    void clear()
    {
        locker.lock();
        now_size = 0;
        frontpos = -1;
        backpos = -1;
        locker.unlock();
    }
    bool full()
    {
        locker.lock();
        if (now_size == max_size)
        {
            locker.unlock();
            return true;
        }
        locker.unlock();
        return false;
    }
    bool empty()
    {
        locker.lock();
        if (now_size == 0)
        {
            locker.unlock();
            return true;
        }
        locker.unlock();
        return false;
        
    }
    //返回最近插入的元素
    bool front(T &val)
    {
        locker.lock();
        if (now_size == 0)
        {
            locker.unlock();
            return false;
        }
        else
        {
            val = *(blockptr + frontpos);
            locker.unlock();
            return true;
        }
    }
    //返回最早插入的元素
    bool back(T &val)
    {
        locker.lock();
        if (now_size == 0)
        {
            locker.unlock();
            return false;
        }
        else
        {
            val = *(blockptr + backpos);
            locker.unlock();
            return true;
        }
    }
    int size()
    {
        int temp = 0;
        locker.lock();
        temp = now_size;
        locker.unlock();
        return temp;
    }
    int maxsize()
    {
        int temp = 0;
        locker.lock();
        temp = max_size;
        locker.unlock();
        return temp;
    }
    bool push(const T val)
    {
        locker.lock();


        if (now_size >= max_size)
        {
            cond.broadsignal();
            locker.unlock();
            return false;
        }
            
        backpos = (backpos + 1) % max_size;
        *(blockptr + backpos) = val;
        now_size++;
        cond.broadsignal();
        locker.unlock();
        return true;
    }
    //清除掉最久的元素
    bool pop(T &val)
    {
        locker.lock();
        while (now_size <= 0)
        {
            if(!cond.wait(locker.get()))
            {
                locker.unlock();
                return false;
            }
        }
        
        frontpos = (frontpos + 1) % max_size;
        val = *(blockptr + frontpos);
        now_size--;
        locker.unlock();
        return true;
    }
};

#endif // BLOCKQUEUE_H
